//
// Created by 17775 on 2024/9/18.
//

#include "LiveMode_PowerProfiles.h"


void LiveMode_PowerProfiles::setPosition_px(QString unit, double sizeX, double sizeY, double dPosX, double dPosY) {
    auto xFactor = unitConversion(unit, sizeX);
    auto yFactor = unitConversion(unit, sizeY);
    x_pos = dPosX * xFactor;
    y_pos = dPosY * yFactor;
    RayCi_LiveMode_PowerProfile_Settings_setPosition_px(_nDocIdLive, x_pos, y_pos);
    emit refreshCenter(x_pos, y_pos);
}

double LiveMode_PowerProfiles::unitConversion(const QString& unit, double size) {
    const std::unordered_map<QString, double> conversionStep {
            {"px", 1.0},
            {"um", 1 / size},
            {"mm", 1000.0 / size},
            {"cm", 10000.0 / size},
            {"in", 10000.0 / 0.3937 / size}
    };
    double factor = 1.0;
    if (conversionStep.find(unit) != conversionStep.end()) {
        factor = conversionStep.at(unit);
    } else {
        factor = 1000000.0 / size;
    }
    return factor;
}

void LiveMode_PowerProfiles::setCursorPosition(double pos) const {
    RayCi_LiveMode_PowerProfile_Cursor_setPosition(_nDocIdLive, pos);
}

double LiveMode_PowerProfiles::getCursorPosition() {
    RayCi_LiveMode_PowerProfile_Cursor_getPosition(_nDocIdLive, &dCurPos);
    return dCurPos;
}

QString LiveMode_PowerProfiles::getUnitSpatial() const {
    char szUnitSpatial_buffer[10];
    int nSize = sizeof(szUnitSpatial_buffer);
    RayCi_LiveMode_PowerProfile_Cursor_getUnitSpatialA(_nDocIdLive, szUnitSpatial_buffer, &nSize);
    return {szUnitSpatial_buffer};
}

double LiveMode_PowerProfiles::getViewCenterXPosition_px() {
    RayCi_LiveMode_PowerProfile_Settings_getPositionX_px(_nDocIdLive, &_positionX_px);
    return _positionX_px;
}

double LiveMode_PowerProfiles::getViewCenterYPosition_px() {
    RayCi_LiveMode_PowerProfile_Settings_getPositionY_px(_nDocIdLive, &_positionY_px);
    return _positionY_px;
}

void LiveMode_PowerProfiles::setCursorPowerFraction(double dFraction) const {
    RayCi_LiveMode_PowerProfile_Cursor_setPowerFraction(_nDocIdLive, dFraction);
}

void LiveMode_PowerProfiles::getFraction() {
    m_cursorPowerFractionThread = std::thread(&LiveMode_PowerProfiles::getCursorPowerFraction, this);
}

void LiveMode_PowerProfiles::getCursorPowerFraction() {
    while(_isGettingNewCursorPowerFraction.load(std::memory_order_acquire)) {
        double dPower = 0;
        bool bValid = false;
        RayCi_LiveMode_Analysis_Statistic_Power_getPower(_nDocIdLive, 0, false, &dPower); // 实际功率
        RayCi_LiveMode_Analysis_CombinedStatistic_Power_isValid(_nDocIdLive, 0, false, &bValid);
        if (bValid) {
            RayCi_LiveMode_Analysis_CombinedStatistic_Power_getPower(_nDocIdLive, 0, false, &dPower);
        }
        bool bPosition = _bIsGettingPowerPosition.load(std::memory_order_acquire);
        if (bPosition) {
            RayCi_LiveMode_PowerProfile_Cursor_getPosition(_nDocIdLive, &dCurPos);
        } else {
            RayCi_LiveMode_PowerProfile_Cursor_getPowerContent(_nDocIdLive, &dCurPos);
            dCurPos = dCurPos / dPower * 100;
            dCurPos = std::floor(dCurPos * 100.0) / 100.0;
        }
//        bPosition ? RayCi_LiveMode_PowerProfile_Cursor_getPosition(_nDocIdLive, &dCurPos) :
//        RayCi_LiveMode_PowerProfile_Cursor_getPowerContent(_nDocIdLive, &dCurPos); // 获取的是设置的百分比，并不是黄色竖线对应位置的百分比
        emit setFractionValue(bPosition, dCurPos);
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }
}

void LiveMode_PowerProfiles::stopCursorPowerFractionThread() {
    _isGettingNewCursorPowerFraction.store(false, std::memory_order_relaxed);
    if(m_cursorPowerFractionThread.joinable()) {
        m_cursorPowerFractionThread.join();
    }
}

void LiveMode_PowerProfiles::getAdjustmentAOI() {
    RayCi_LiveMode_PowerProfile_Adjustment_getAoi(_nDocIdLive, &_iIdAOI);
}

void LiveMode_PowerProfiles::getAdjustmentMethod() {
    RayCi_LiveMode_PowerProfile_Adjustment_getMethod(_nDocIdLive, &_iMethod);
}

void LiveMode_PowerProfiles::setAxisRatio(double dRatioX, double dRatioY) const {
    RayCi_LiveMode_PowerProfile_Settings_setAxisRatio(_nDocIdLive, dRatioX, dRatioY);
}

void LiveMode_PowerProfiles::setAdjustmentActive(bool bActive) const {
    RayCi_LiveMode_PowerProfile_Adjustment_setActive(_nDocIdLive, bActive);
}

void LiveMode_PowerProfiles::setAdjustmentAOI(int iIdAOI) const {
    RayCi_LiveMode_PowerProfile_Adjustment_setAoi(_nDocIdLive, iIdAOI);
}

void LiveMode_PowerProfiles::setAdjustmentMethod(int iMethod) const {
    RayCi_LiveMode_PowerProfile_Adjustment_setMethod(_nDocIdLive, iMethod);
}

void LiveMode_PowerProfiles::closePowerProfileWindow() const {
    RayCi_LiveMode_PowerProfile_Window_close(_nDocIdLive);
}

LiveMode_PowerProfiles::~LiveMode_PowerProfiles() {
    _isGettingNewCursorPowerFraction.store(false, std::memory_order_release);
    if(m_cursorPowerFractionThread.joinable()) {
        m_cursorPowerFractionThread.join();
    }
}